Skip to content

fix(context): 修复达到最大轮数后续跑上下文丢失问题#290

Merged
phantom5099 merged 1 commit into
1024XEngineer:mainfrom
wynxing:refix_br
Apr 14, 2026
Merged

fix(context): 修复达到最大轮数后续跑上下文丢失问题#290
phantom5099 merged 1 commit into
1024XEngineer:mainfrom
wynxing:refix_br

Conversation

@wynxing

@wynxing wynxing commented Apr 14, 2026

Copy link
Copy Markdown
Collaborator

背景

源码分析类任务在连续多轮执行后,存在两类续跑不稳问题:

  1. 普通续跑时,读时消息裁剪窗口过小,较早的 read_file 结果会在未触发 compact 前先被裁掉。
  2. 命中 max_loops 退出时,runtime 直接报错结束,未先沉淀 durable TaskState + compact summary,导致后续输入“继续”时主要依赖最近消息窗口。

本次修改

  • 新增 context.compact.read_time_max_message_spans 配置项,并提供默认值 24
  • 将读时 trim 从硬编码窗口改为读取配置,缓解普通续跑时的上下文过早丢失
  • 新增 compact mode loop_limit
  • runtime.Run() 命中 max_loops 前,best-effort 执行一次 loop_limit continuation checkpoint
  • continuation checkpoint 成功时:
    • 回写 compact 后的 session.Messages
    • 回写 session.TaskState
    • 重置累计 token
    • 发出 compact_start / compact_done
    • 最终仍以可恢复错误结束当前 run
  • continuation checkpoint 失败或 no-op 时,保持原有退出语义
  • 补齐新配置项的序列化 / 反序列化 / 默认值 / 校验测试
  • 补齐 loop_limit 成功与失败分支的 runtime 测试
  • 更新配置与 compact 相关文档

影响

  • “继续分析”场景下,文件读取结果更不容易在普通续跑中被过早裁掉
  • 达到最大轮数后,后续续跑会优先依赖 durable checkpoint,而不是只依赖最近几条消息
  • 不改变 auto_compact 默认关闭的现状
  • 不修改 filesystem_read_file 的 micro compact 策略,行为面保持最小

验证

  • go test ./internal/runtime
  • go test ./internal/config ./internal/context
  • go test ./...

@codecov

codecov Bot commented Apr 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.10345% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/runtime/run.go 85.71% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

整体审查完成(代码质量、性能、安全、文档一致性)。

未发现阻塞问题,留下一条非阻塞性能建议供参考。

Comment thread internal/runtime/run.go
@@ -71,7 +71,21 @@ func (s *Service) Run(ctx context.Context, input UserInput) error {
for turn := 0; ; turn++ {
maxLoops := resolveMaxLoops(s.configManager.Get())
if turn >= maxLoops {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

非阻塞建议:这里在命中 max_loops 时无条件尝试 loop_limit compact checkpoint。该行为与本 PR 目标一致,但会把“退出路径”变成潜在重操作路径(额外 compact + 持久化)。如果后续观察到高频 max_loops 场景的尾延迟上升,可考虑增加一个轻量开关(例如仅在 continue 语义输入或配置显式开启时执行 checkpoint)。

@phantom5099 phantom5099 merged commit 15d0486 into 1024XEngineer:main Apr 14, 2026
2 checks passed
@minorcell

Copy link
Copy Markdown
Member

@Yumiue

我觉得这里的 max_steps 没有太强的必要性,尤其对于长时间运行的 agent 来说,它更像是一个框架层的人工中断,而不是任务本身的自然终止条件。

一个任务需要多少步,通常取决于问题复杂度、工具调用粒度和中间状态设计,而不是一个预先设定的固定数字。所以把 agent 在第 N 步强行停掉,很多时候并不代表它进入了异常状态,只是说明任务还没做完。

如果这里的目的是防止上下文无限膨胀,那更合理的手段应该是压缩 / summarization / checkpoint,而不是 max_steps。如果压缩链路是可信的,agent 应该可以持续工作;如果压缩链路不可信,那我们需要修的是压缩能力本身,而不是引入一个步数上限来掩盖问题。

我更建议去掉这个限制,或者至少不要把它作为核心终止条件。相比 max_steps,更值得保留的是这些 guardrail:

  • wall-clock time / token budget
  • 连续若干轮没有新进展
  • 重复调用相同工具或进入明显循环

这些约束和真实失败模式更相关,也不会无谓地阻碍长任务执行。

@minorcell

Copy link
Copy Markdown
Member

@xgopilot 帮我上面的评论创建一个issue,并派发给 @Yumiue 修复。

@fennoai

fennoai Bot commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

处理结果

已根据你上面的评论创建 issue,并已指派给 @Yumiue

未执行项:未做代码修改(本次需求仅为创建并派发 issue)。

View job run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants